home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / os2 / pvm34b3.zip / pvm34b3 / pvm3 / rm / srm.c < prev    next >
C/C++ Source or Header  |  1997-07-22  |  23KB  |  967 lines

  1.  
  2. static char rcsid[] =
  3.     "$Id: srm.c,v 1.1 1997/07/15 17:59:23 pvmsrc Exp $";
  4.  
  5. /*
  6.  *         PVM version 3.4:  Parallel Virtual Machine System
  7.  *               University of Tennessee, Knoxville TN.
  8.  *           Oak Ridge National Laboratory, Oak Ridge TN.
  9.  *                   Emory University, Atlanta GA.
  10.  *      Authors:  J. J. Dongarra, G. E. Fagg, M. Fischer
  11.  *          G. A. Geist, J. A. Kohl, K. S. London, R. J. Manchek,
  12.  *    P. Mucci, P. M. Papadopoulos, S. L. Scott, and V. S. Sunderam
  13.  *                   (C) 1997 All Rights Reserved
  14.  *
  15.  *                              NOTICE
  16.  *
  17.  * Permission to use, copy, modify, and distribute this software and
  18.  * its documentation for any purpose and without fee is hereby granted
  19.  * provided that the above copyright notice appear in all copies and
  20.  * that both the copyright notice and this permission notice appear in
  21.  * supporting documentation.
  22.  *
  23.  * Neither the Institutions (Emory University, Oak Ridge National
  24.  * Laboratory, and University of Tennessee) nor the Authors make any
  25.  * representations about the suitability of this software for any
  26.  * purpose.  This software is provided ``as is'' without express or
  27.  * implied warranty.
  28.  *
  29.  * PVM version 3 was funded in part by the U.S. Department of Energy,
  30.  * the National Science Foundation and the State of Tennessee.
  31.  */
  32.  
  33.  
  34. #include <stdio.h>
  35. #include <string.h>
  36. #include <sys/time.h>
  37. #include "pvm3.h"
  38. #include "pvmproto.h"
  39. #include "pvmtev.h"
  40. #include "../src/global.h"
  41. #include "srm.h"
  42.  
  43.  
  44. int
  45. main(argc, argv)
  46. int     argc;
  47. char    *argv[];
  48. {
  49.   HOST_HEAD.next = NULL;
  50.   HOST_HEAD.prev = NULL;
  51.   TASK_HEAD.next = NULL;
  52.   TASK_HEAD.prev = NULL;
  53.   loop_init();
  54.   return 0;
  55. }
  56.  
  57. int
  58. start_pvm()
  59. {
  60.     int            cc, i, narch, nhost, ntask, se;
  61.     struct pvmhostinfo     *hosts;
  62.         struct pvmtaskinfo     *tasks;
  63.  
  64.     pvm_setopt( PvmResvTids, 1 );
  65.     pvm_setopt( PvmRoute, PvmDontRoute );
  66.     se = pvm_setopt( PvmAutoErr, 0 );
  67.     cc = pvm_start_pvmd( 0, (char **) "", FALSE );
  68.     if ( cc < 0 )
  69.         {
  70.                 if ( cc == PvmDupHost )
  71.                 {
  72.                         printf( "Connecting to PVMD already running... \n" );
  73.                         fflush( stdout );
  74.                 }
  75.  
  76.                 else
  77.                 {
  78.                         pvm_perror( "Can't Start PVM" );
  79.                         exit( -1 );
  80.                 }
  81.         }
  82.         else
  83.         {
  84.                 printf( "New PVMD started...\n" );
  85.                 fflush( stdout );
  86.         }
  87.  
  88.         pvm_setopt( PvmResvTids, 1 );
  89.  
  90.         /* Get My TID */
  91.  
  92.         MYTID = pvm_mytid();
  93.  
  94.         if ( MYTID < 0 )
  95.         {
  96.                 pvm_perror( "Error Joining PVM" );
  97.  
  98.                 exit( -1 );
  99.         }
  100.  
  101.         else
  102.                 printf( "SRM connected as TID=0x%x.\n", MYTID );
  103.         if (pvm_reg_rm(&our_host) != PvmOk)
  104.         {
  105.                 pvm_perror( "Error registering as Resource Manager" );
  106.                 exit( -1 );
  107.         }
  108.         else
  109.                 printf( "SRM registered as Resource Manager.\n");
  110.  
  111.  
  112.          /* Need to do a config otherwise the first host gets messed up 
  113.         if we start the daemon */
  114.          pvm_config ( &nhost, &narch, &hosts );
  115.          for ( i = 0; i < nhost; i++ )
  116.                   add_host ( &(hosts[i]) );
  117.          pvm_tasks(0, &ntask, &tasks);
  118.          for ( i = 0; i < ntask; i++ )
  119.             if ( tasks[i].ti_tid != MYTID )
  120.                   add_task( &(tasks[i]));
  121. }
  122.  
  123.  
  124. int
  125. loop_init()
  126. {
  127.     int buf, id, found, handled, i, msgtag, msgtid;
  128.     struct pvmminfo info;
  129.  
  130.  
  131.     start_pvm ( );
  132.  
  133.     for ( ;; ) {
  134.         handled = 0;
  135.         buf = pvm_recv(-1, -1);
  136.         pvm_bufinfo(buf, 0, &msgtag, &msgtid);
  137.         pvm_getminfo(buf, &info);
  138.  
  139.         for ( i=0; i < MAX_MESSAGE; i++ )
  140.             if (msgtag == Messages[i].msg_tag) {
  141. #ifdef MESSAGE_ON
  142.               printf ("PVMd message is %s from t%x\n",
  143.                 pvmnametag(msgtag,&found), msgtid );
  144. #endif
  145.             Messages[i].code(msgtid, info);
  146.             handled = 1;
  147.             break;
  148.             }
  149. #ifdef DEBUG_RM
  150.         if ( !handled )
  151.             printf ("Unexpected message with tag %d from t%x\n",
  152.                 msgtag, msgtid );
  153. #endif
  154.     }
  155. }
  156.     
  157.  
  158. int    
  159. sm_spawn(who, info)
  160. int    who;
  161. struct    pvmminfo *info;
  162. {
  163.         char    arch[100], buf[1000], new_buf[1000], where[100];
  164.         int     arg_count, count, dest, env_count, flag, i, j, new_tid;
  165.         int    ret_count, sbuf, trc_ctx, trc_tag, trc_tid, out_ctx, out_tag;
  166.     int    out_tid, one = 1;
  167.         char    **argv, **env;
  168.         struct  pvmtaskinfo             tinfo;
  169.  
  170.     pvm_upkstr ( buf );
  171.     pvm_upkint ( &flag, 1, 0 );
  172.     pvm_upkstr ( where );
  173.     pvm_upkint ( &count, 1, 0 );
  174.  
  175.     arg_count =    unpack_list (&argv);
  176.  
  177.     pvm_upkint ( &out_tid, 1, 1 );
  178.     pvm_upkint ( &out_ctx, 1, 1 );
  179.     pvm_upkint ( &out_tag, 1, 1 );
  180.     pvm_upkint ( &trc_tid, 1, 1 );
  181.     pvm_upkint ( &trc_ctx, 1, 1 );
  182.     pvm_upkint ( &trc_tag, 1, 1 );
  183.             
  184.     env_count  =    unpack_list (&env);
  185. #ifdef DEBUG_RM
  186.     printf ("Buf %s, Flag %d, Where %s, Out_Tid t%x, Out_ctx %x\n",
  187.         buf, flag, where, out_tid, out_ctx);
  188.     printf ("Out_tag %x, Trc_tid %x, Trc_ctx %x, Trc_tag %x\n",
  189.         out_tag, trc_tid, trc_ctx, trc_tag );
  190. #endif
  191.     pvm_initsend(PvmDataFoo);
  192.     pvm_pkint ( &count, 1, 1);
  193.     pvm_setminfo ( pvm_getsbuf(), info );
  194.     
  195.     for ( i = 0; i < count; i++ ) {
  196.         dest = select_host ( flag, arch );
  197.         if ( dest ) {
  198.             sbuf = pvm_setsbuf (pvm_mkbuf(PvmDataFoo));
  199.             pvm_pkint(&who, 1, 1);
  200.                         pvm_pkstr(buf);
  201.                         pvm_pkint(&flag, 1, 1);
  202.                         pvm_pkint(&one, 1, 1);
  203.             pvm_pkint (&arg_count, 1, 1);
  204.             for (j = 0; j < arg_count; j++) 
  205.                 pvm_pkstr ( argv[j] );
  206.             pvm_pkint(&out_tid, 1, 1);
  207.             pvm_pkint(&out_ctx, 1, 1);
  208.                         pvm_pkint(&out_tag, 1, 1);
  209.                         pvm_pkint(&trc_tid, 1, 1);
  210.             pvm_pkint(&trc_ctx, 1, 1);
  211.                         pvm_pkint(&trc_tag, 1, 1);
  212.                         pvm_pkint(&env_count, 1, 1);
  213.             sprintf(new_buf, "PVMTMASK=%s", pvmctrc.tmask);
  214.                         pvm_pkstr(new_buf);
  215.                         sprintf(new_buf, "PVMTRCBUF=%d", pvmctrc.trcbuf);
  216.                         pvm_pkstr(new_buf);
  217.                         sprintf(new_buf, "PVMTRCOPT=%d", pvmctrc.trcopt);
  218.                         pvm_pkstr(new_buf);
  219.                         sprintf(new_buf, "PVMCTX=0x%x", pvmmyctx);
  220.                         pvm_pkstr(new_buf);
  221.  
  222.                         for (j = 0; j < env_count; j++) 
  223.                                 pvm_pkstr( env[j] );
  224.             pvm_setminfo ( pvm_getsbuf(), info );
  225.                         pvm_send(dest | TIDPVMD, SM_EXEC);
  226.  
  227.                         pvm_freebuf(pvm_setsbuf(sbuf));
  228.                         pvm_recv(-1, SM_EXECACK);
  229.                         pvm_upkint(&ret_count, 1, 1);
  230.                         if (ret_count != 1) {
  231.                                 printf("sm_spawn: unexpected return count: %d\n"
  232. , ret_count);
  233.                         }
  234.                         pvm_upkint(&new_tid, 1, 1);
  235.                         pvm_pkint(&new_tid, 1, 1);
  236.  
  237.                         tinfo.ti_tid = new_tid;
  238.                         tinfo.ti_ptid = who;
  239.                         tinfo.ti_host = dest;
  240. /*
  241.                         tinfo.ti_flag = 0x00000000;
  242. */
  243.                         tinfo.ti_flag = flag;
  244.                         tinfo.ti_a_out = buf;
  245. /*
  246.                         tinfo.ti_pid = 0; 
  247. */
  248.             add_task(&tinfo);
  249.                 } else {
  250.                         new_tid = PvmNoHost;
  251.                         pvm_pkint(&new_tid, 1, 1);
  252.                 }
  253.         }
  254.         pvm_send(who, SM_SPAWN);
  255.         free_list(argv, arg_count - 2);
  256.         free_list(env, env_count);
  257.     return 0;
  258. }
  259.  
  260. int
  261. sm_exec(who, info)
  262. int    who;
  263. struct    pvmminfo    *info;
  264. {
  265. #ifdef DEBUG_RM
  266.     printf("sm_exec: Should mot be called!\n");
  267. #endif
  268.     return 0;
  269. }
  270.  
  271. int
  272. sm_execack(who, info)
  273. int     who;
  274. struct    pvmminfo    *info;
  275. {
  276.     int    count, i;
  277.     struct  pvmtaskinfo    task;
  278.  
  279.     pvm_upkint ( &count, 1, 1 );
  280.         pvm_upkint(&(task.ti_tid), 1, 1);
  281. /*
  282.         task.ti_ptid = PvmNoParent;
  283. */
  284.         task.ti_ptid = 0;
  285.         task.ti_host = pvm_tidtohost( task.ti_tid );
  286.         task.ti_flag = 0x00000000;
  287.         task.ti_a_out = "\0";
  288.         task.ti_pid = 0;
  289.         add_task( &task );
  290.     return 0;
  291. }
  292.  
  293. int
  294. sm_task(who, info)
  295. int    who;
  296. struct    pvmminfo    *info;
  297. {
  298.         int             error, where;
  299.  
  300.         pvm_upkint(&where, 1, 1);
  301.         pvm_initsend(PvmDataFoo);
  302.     pvm_setminfo ( pvm_getsbuf(), info );
  303.         pvm_pkint(&error, 1, 1 );
  304.         pack_task_list(where);
  305.         pvm_send(who, SM_TASK);
  306.     return 0;
  307. }
  308.  
  309. int
  310. sm_config(who, info)
  311. int    who;
  312. struct pvmminfo *info;
  313. {
  314.         pvm_initsend(PvmDataFoo);
  315.     pvm_setminfo ( pvm_getsbuf(), info );
  316.         pack_host_list();
  317.         pvm_send(who, SM_CONFIG);
  318.     return 0;
  319. }
  320.  
  321. int
  322. sm_addhost(who, info)
  323. int    who;
  324. struct pvmminfo    *info;
  325. {
  326.         int                 count,  i, narches;
  327.         char            new_host_arch[100], new_host_name[100];
  328.         char            **host_names;
  329.         struct  pvmhostinfo     newhost;
  330.  
  331.  
  332.         count = unpack_list(&host_names);
  333.         pvm_initsend(PvmDataFoo);
  334.     pvm_setminfo ( pvm_getsbuf(), info );
  335.         pvm_pkint(&count, 1, 1);
  336.  
  337.         for (i = 0; i < count; i++) 
  338.                 pvm_pkstr( host_names[i] );
  339.  
  340.         pvm_send(our_host->hi_tid | TIDPVMD, SM_ADD);
  341.     pvm_recv(-1, SM_ADDACK);
  342.     
  343.  
  344.         pvm_upkint(&count, 1, 1);
  345.         pvm_upkint(&narches, 1, 1);
  346.  
  347.         pvm_initsend(PvmDataFoo);
  348.     pvm_setminfo ( pvm_getsbuf(), info );
  349.  
  350.         pvm_pkint(&count, 1, 1);
  351.         pvm_pkint(&narches, 1, 1);
  352.  
  353.  
  354. #ifdef DEBUG_RM
  355.     printf ("Count %d: Arch: %d  Tid %d\n", count, narches, newhost.hi_tid);
  356. #endif
  357.         if ( count > 0 ) {
  358.                 newhost.hi_name = new_host_name;
  359.                 newhost.hi_arch = new_host_arch;
  360.                 for (i = 0; i < count; i++) {
  361.                         pvm_upkint(&newhost.hi_tid, 1, 1);
  362. #ifdef DEBUG_RM
  363.             printf ("%x\n", newhost.hi_tid);
  364. #endif
  365.             if ( newhost.hi_tid > 0 ) /* Error */
  366.             {
  367.                             pvm_upkstr( new_host_name );
  368.                             pvm_upkstr( new_host_arch );
  369.                             pvm_upkint(&newhost.hi_speed, 1, 1);
  370.                 pvm_upkint(&newhost.hi_dsig, 1, 1);
  371. #ifdef DEBUG_RM
  372.                 printf ("%s %s %d sig%x\n",
  373.                 new_host_name,new_host_arch,newhost.hi_speed,
  374.                 newhost.hi_dsig);
  375. #endif
  376.                             add_host( &newhost );
  377.             }
  378.                         pvm_pkint(&newhost.hi_tid, 1, 1);
  379.                         pvm_pkstr( new_host_name );
  380.                         pvm_pkstr( new_host_arch );
  381.                         pvm_pkint(&newhost.hi_speed, 1, 1);
  382.             pvm_pkint(&newhost.hi_dsig, 1, 1);
  383.                 }
  384.         }
  385.  
  386.         pvm_send(who, SM_ADDHOST);
  387.         free_list(host_names, count);
  388.     return 0;
  389. }
  390.  
  391. int
  392. sm_delhost(who, info)
  393. int    who;
  394. struct  pvmminfo    *info;
  395. {
  396.         char            **host_names;
  397.         int                 count, i, rc;
  398.         int                 *status;
  399.     struct    pvmminfo    temp_info;
  400.  
  401.     temp_info = *info;
  402.  
  403.         count = unpack_list(&host_names);
  404.         status = (int *) malloc( count * sizeof(int) );
  405.  
  406.     /* Can't just use rc since we recursively call pvm_delhosts KSL */
  407.  
  408.         rc = pvm_delhosts( host_names, count, status );
  409.     pvm_initsend(PvmDataFoo);
  410.     pvm_setminfo ( pvm_getsbuf(), &temp_info );
  411.  
  412.         if ( rc == 0 ) /* XXX Look just don't ask KSL */
  413.         pvm_pkint(&count, 1, 1);
  414.     else
  415.             pvm_pkint(&rc, 1, 1);
  416.     
  417.     pvm_pkint(status, 1, 1);
  418.     pvm_send ( who, SM_DELHOST);
  419.         free(status);
  420.         free_list(host_names, count);
  421.     return 0;
  422. }
  423.  
  424. int 
  425. sm_add(who, info)
  426. int    who;
  427. struct    pvmminfo    *info;
  428. {
  429. #ifdef DEBUG_RM
  430.     printf("sm_add: Should not be called!\n");
  431. #endif
  432.     return 0;
  433. }
  434.  
  435. int 
  436. sm_addack(who, info)
  437. int    who;
  438. struct    pvmminfo    *info;
  439. {
  440. #ifdef DEBUG_RM
  441.     printf("sm_addack: Should not be called!\n");
  442. #endif
  443.     return 0;
  444. }
  445.  
  446. int 
  447. sm_notify(who, info)
  448. int    who;
  449. struct    pvmminfo    *info;
  450. {
  451.         int             count, ctx, flags, msg_id, notify_tid;
  452.  
  453.         pvm_upkint(&flags, 1, 1);
  454.     pvm_upkint(&ctx, 1, 1);
  455.         pvm_upkint(&msg_id, 1, 1);
  456.         pvm_upkint(&count, 1, 1);
  457.         if ( flags == PvmHostAdd ) {
  458.                 new_notification(flags, who, msg_id, count, ctx);
  459.         } else {
  460.                 for (; count > 0; count--) {
  461.                         pvm_upkint(¬ify_tid, 1, 1);
  462.                         new_notification(flags, who, msg_id, notify_tid, ctx);
  463.                 }
  464.         }
  465.     return 0;
  466. }
  467.  
  468. int 
  469. sm_taskx(who, info)
  470. int    who;
  471. struct    pvmminfo    *info;
  472. {
  473.     int    i, status, tid;
  474.  
  475.     pvm_upkint (&tid, 1, 1);
  476.  
  477.     for ( i = 0; i < num_notifys; i++ )
  478.         if ( notifylist[i].for_who == who )
  479.         del_notification(notifylist[i].for_who,
  480.            notifylist[i].on_tid);
  481.     delete_task ( tid );    
  482.     pvm_upkint (&status, 1, 1);
  483. #ifdef DEBUG_RM
  484.     printf ("sm_taskx: Task t%x, exit with status 0x%x\n", tid, status);
  485. #endif
  486.     return 0;
  487. }
  488.  
  489. int 
  490. sm_hostx(who, info)
  491. int    who;
  492. struct    pvmminfo    *info;
  493. {
  494.     int    error, i, tid;
  495.     
  496.     pvm_upkint (&tid, 1, 1);
  497.     tid += TIDPVMD; /*Quick and Dirty fix */
  498. #ifdef DEBUG_RM
  499.     printf ("t%x\n", tid );
  500. #endif
  501.     for ( i = 0; i < num_notifys; i++ )
  502.         if ( notifylist[i].for_who == who )
  503.         del_notification(notifylist[i].for_who,
  504.            notifylist[i].on_tid);
  505.     error = delete_host ( tid );
  506. #ifdef DEBUG_RM
  507.     if ( error != -1 )
  508.         printf ("sm_hostx: Host t%x deleted.\n", tid);
  509. #endif
  510.     return 0;
  511. }
  512.  
  513. int
  514. sm_handoff(who, info)
  515. int    who;
  516. struct    pvmminfo    *info;
  517. {
  518. #ifdef DEBUG_RM
  519.     printf ("sm_handoff: This should not be called!\n");
  520. #endif
  521.     return 0;
  522. }
  523.  
  524. int
  525. sm_sched(who, info)
  526. int    who;
  527. struct    pvmminfo    *info;
  528. {
  529.     int        error;
  530.  
  531.     pvm_initsend ( PvmDataDefault );
  532.     pvm_setminfo ( pvm_getsbuf(), info );
  533.     pvm_pkint ( &error, 1, 1 );
  534.     pvm_send (who, SM_SCHED);
  535.     return 0;
  536. }
  537.  
  538. int
  539. sm_sthost(who, info)
  540. int    who;
  541. struct    pvmminfo    *info;
  542. {
  543. #ifdef DEBUG_RM
  544.     printf ("sm_sthost: This should not be called!\n");
  545. #endif
  546.     return 0;
  547. }
  548.  
  549. int
  550. sm_sthostack(who, info)
  551. int    who;
  552. struct    pvmminfo    *info;
  553. {
  554. #ifdef DEBUG_RM
  555.     printf ("sm_sthostack: This should not be called!\n");
  556. #endif
  557.     return 0;
  558. }
  559.  
  560. int
  561. add_host (host)
  562. struct pvmhostinfo    *host;
  563. {
  564.     host_type    *next_host, *new_host, *temp_host;
  565.     bool        found_arch = FALSE;
  566.     bool        found_host = FALSE;
  567.     
  568.     temp_host = &(HOST_HEAD);
  569.     for (next_host=HOST_HEAD.next;next_host;next_host=next_host->next)
  570.     {
  571.          if(!found_arch&&!strcmp( next_host->entry.hi_arch,host->hi_arch))
  572.             found_arch = TRUE;
  573.         temp_host = next_host;
  574.         if ( next_host->entry.hi_tid == host->hi_tid )
  575.         {
  576.             found_host = TRUE;
  577.             break;
  578.         }
  579.     }
  580.  
  581.     if ( found_host )
  582.     {
  583. #ifdef DEBUG_RM
  584.         printf ("Host t%x already in the list.\n", host->hi_tid);
  585. #endif
  586.         return -1;
  587.     }
  588.     
  589.     if ( !found_arch )
  590.         num_arches++;
  591.     
  592.     new_host = (host_type *) malloc (sizeof (host_type) );
  593.     temp_host->next = new_host;
  594.     new_host->prev = temp_host;
  595.     new_host->next = NULL;
  596.     new_host->load = 0;
  597.     new_host->entry.hi_tid    =    host->hi_tid;
  598.     new_host->entry.hi_name    =    (char *) strdup(host->hi_name);
  599.     new_host->entry.hi_arch =    (char *) strdup(host->hi_arch);
  600.     new_host->entry.hi_speed=    host->hi_speed;
  601.     new_host->entry.hi_dsig    =    host->hi_dsig;
  602.     send_notification(PvmHostAdd, host->hi_tid);
  603.         num_hosts++;
  604. #ifdef DEBUG_RM
  605.     printf ( "Adding host t%x\n", host->hi_tid );
  606.     print_host_contents();
  607. #endif
  608.     return 0;
  609. }
  610.  
  611. int
  612. add_task (task)
  613. struct pvmtaskinfo    *task;
  614. {
  615.     task_type    *next_task, *new_task, *temp_task;
  616.     host_type    *host;
  617.  
  618.     temp_task = &TASK_HEAD;
  619.     for(next_task=TASK_HEAD.next;next_task;next_task=next_task->next)
  620.     {
  621.         if (next_task->entry.ti_tid == task->ti_tid)
  622.         { 
  623. #ifdef DEBUG_RM
  624.             printf ("Task already added\n");
  625. #endif
  626.             return;
  627.         }
  628.         temp_task = next_task;
  629.     }
  630.     new_task = (task_type *) malloc (sizeof (task_type) );
  631.     temp_task->next = new_task;
  632.     new_task->prev = temp_task;
  633.     new_task->next = NULL;
  634.     new_task->entry.ti_tid    =    task->ti_tid;
  635.     new_task->entry.ti_ptid    =    task->ti_ptid;
  636.     new_task->entry.ti_host =    task->ti_host;
  637.     new_task->entry.ti_flag =    task->ti_flag;
  638.     new_task->entry.ti_a_out=    (char *) strdup( task->ti_a_out );
  639.     new_task->entry.ti_pid  =    task->ti_pid;
  640.     host = find_host( task->ti_host );
  641.     if ( host )
  642.         host->load++;
  643. #ifdef DEBUG_RM
  644.     else
  645.         printf ("Hmmmm no host found for t%x", task->ti_host );
  646.     printf ("Adding task t%x\n", task->ti_tid );
  647. #endif
  648.     return 0;
  649. }
  650.  
  651. int
  652. select_host (flag, where)
  653. int    flag;
  654. char *    where;
  655. {
  656.     host_type  *best_host, *next_host;
  657.  
  658.     /* Put load balancing code here */
  659.     next_host = HOST_HEAD.next;
  660.     best_host = HOST_HEAD.next;
  661.     for ( ; next_host ; next_host = next_host->next ) {
  662.         if ( (flag & PvmTaskArch) && 
  663.             strcmp(where, next_host->entry.hi_name) ) 
  664.                 continue;
  665.         if ( (flag & PvmTaskHost) &&
  666.             strcmp(where, next_host->entry.hi_name) )
  667.                 continue;
  668.         if ( next_host->load < best_host->load )
  669.             best_host = next_host;
  670.     }
  671.     if ( best_host->entry.hi_tid == our_host->hi_tid )
  672.         return TIDPVMD;
  673.     else
  674.         return best_host->entry.hi_tid;
  675. }
  676.  
  677. int
  678. delete_host ( tid )
  679. int    tid;
  680. {
  681.     host_type    *next, *next_host;    
  682.     bool        found = FALSE;
  683.     
  684.     for ( next = HOST_HEAD.next; next; next = next->next )
  685.         if ( next->entry.hi_tid == tid )
  686.         {
  687.             found = TRUE;
  688.             break;
  689.         }
  690. #ifdef DEBUG_RM
  691.         else
  692.             printf ("Not t%x", next->entry.hi_tid );
  693. #endif
  694.     
  695.     if ( !found )
  696.     {
  697. #ifdef DEBUG_RM
  698.         printf ( "delete_host:  Host t%x not found.\n\r", tid );
  699. #endif
  700.         return -1;
  701.     }
  702.  
  703.     found = FALSE;
  704.     for (next_host=HOST_HEAD.next;next_host;next_host=next_host->next)
  705.         if (!strcmp (next_host->entry.hi_arch, next->entry.hi_arch) )
  706.         {
  707.             found = TRUE;
  708.             break;
  709.         }
  710.     if ( !found )
  711.         num_arches--;
  712.     next->prev->next = next->next;
  713.     if ( next->next )
  714.         next->next->prev = next->prev;
  715.     free ( next );
  716.     num_hosts--;
  717.         return 0;
  718. }
  719.  
  720. int
  721. delete_task ( tid )
  722. int    tid;
  723. {
  724.     host_type    *host;
  725.     task_type    *next;
  726.     bool        found = FALSE;
  727.     
  728.     for (    next = TASK_HEAD.next; next; next = next->next)
  729.         if ( next->entry.ti_tid == tid )
  730.         {
  731.             found = TRUE;
  732.             break;
  733.         }
  734.  
  735.     if ( !found )
  736.     {
  737. #ifdef DEBUG_RM
  738.         printf ("delete_task: Task t%x not found.\n", tid );
  739. #endif
  740.         return -1;
  741.     }
  742.  
  743.     host = find_host ( next->entry.ti_host );
  744.     if ( host )
  745.         host->load--;
  746. #ifdef DEBUG_RM
  747.     else
  748.         printf ("Hmmm host t%x not found\n", next->entry.ti_host );
  749. #endif
  750.     next->prev->next = next->next;
  751.     if ( next->next )
  752.         next->next->prev = next->prev;
  753.     free ( next );
  754.     return 0;
  755. }
  756.  
  757. int
  758. unpack_list(str_list)
  759. char    ***str_list;
  760. {
  761.         int             i, count = 0;
  762.         char        temp_str[1000];
  763.  
  764.         pvm_upkint( &count, 1, 1 );
  765.         *str_list = (char **) malloc( (count + 1) * sizeof(char *));
  766.         for (i = 0 ; i < count; i++ ) {
  767.                 pvm_upkstr( temp_str );
  768.                 (*str_list)[i] = (char *) strdup( temp_str );
  769.         }
  770.         (*str_list)[i] = 0;
  771.         return count;
  772. }
  773.  
  774. int
  775. free_list(str_list, count)
  776. char    **str_list;
  777. int             count;
  778. {
  779.         int             i;
  780.  
  781.         for (i = 0; i < count; i++) {
  782.                 free(str_list[i]);
  783.         }
  784.         free(str_list);
  785.     return 0;
  786. }
  787.  
  788. int
  789. pack_host(host)
  790. struct pvmhostinfo      *host;
  791. {
  792.         pvm_pkint(&(host->hi_tid), 1, 1);
  793.         pvm_pkstr(host->hi_name);
  794.         pvm_pkstr(host->hi_arch ? host->hi_arch : "" );
  795.         pvm_pkint(&(host->hi_speed), 1, 1);
  796.     pvm_pkint(&(host->hi_dsig), 1, 1);
  797.     return 0;
  798. }
  799.  
  800.  
  801. int
  802. pack_host_list()
  803. {
  804.         host_type             *next_host;
  805.  
  806.         pvm_pkint(&num_hosts, 1, 1);
  807.         pvm_pkint(&num_arches, 1, 1);
  808.     for ( next_host = HOST_HEAD.next;next_host;next_host=next_host->next)
  809.                 pack_host(&(next_host->entry));
  810.     return 0;
  811. }
  812.  
  813. int
  814. pack_task(task)
  815. task_type         *task;
  816. {
  817.         pvm_pkint(&(task->entry.ti_tid), 1, 1);
  818.         pvm_pkint(&(task->entry.ti_ptid), 1, 1);
  819.         pvm_pkint(&(task->entry.ti_host), 1, 1);
  820.         pvm_pkint(&(task->entry.ti_flag), 1, 1);
  821.         pvm_pkstr(task->entry.ti_a_out);
  822.         pvm_pkint(&(task->entry.ti_pid), 1, 1);
  823.     return 0;
  824. }
  825.  
  826.  
  827. int
  828. pack_task_list(where)
  829. int             where;
  830. {
  831.     task_type    *next_task;
  832.     host_type    *host;
  833.  
  834.         host = find_host(where);
  835.     for (next_task=TASK_HEAD.next; next_task; next_task = next_task->next)
  836.     {
  837.         if ( where == 0 || (host != NULL && 
  838.             next_task->entry.ti_host == host->entry.hi_tid ) ||
  839.             ( next_task->entry.ti_tid == where ) )
  840.                             pack_task(next_task);
  841.         }
  842.     return 0;
  843. }
  844.  
  845. host_type *
  846. find_host(tid)
  847. int             tid;
  848. {
  849.     host_type    *next_host;
  850.  
  851.     for ( next_host = HOST_HEAD.next;next_host;next_host=next_host->next )
  852.         if ( next_host->entry.hi_tid == tid )
  853.             return next_host;
  854.     return HOST_HEAD.next; /* XXX Needs to be fixed */
  855. }
  856.  
  857. int
  858. send_notification(kind, on_tid)
  859. int             kind, on_tid;
  860. {
  861.         int                 i, sbuf;
  862.         struct  pvmhostinfo     *notify_host;
  863.     host_type        *host;
  864.  
  865.         for (i = 0; i < num_notifys; i++) {
  866.                 if (notifylist[i].kind == kind && ((kind == PvmHostAdd) ||
  867.  
  868.    (notifylist[i].on_tid == on_tid))) {
  869.                         sbuf = pvm_setsbuf(pvm_mkbuf(PvmDataFoo));
  870.                         if (kind == PvmTaskExit) {
  871.                                 pvm_pkint(&on_tid, 1, 1);
  872.                         } else {
  873.                                 host = find_host(on_tid);
  874.                                 notify_host = &(host->entry);
  875.                                 pack_host(notify_host);
  876.                         }
  877.                         pvm_send(notifylist[i].for_who, notifylist[i].msg_tag);
  878.                         pvm_freebuf(pvm_setsbuf(sbuf));
  879.                 }
  880.         }
  881.     return 0;
  882. }
  883.  
  884.  
  885. int
  886. del_notification(for_who, on_tid)
  887. int             for_who, on_tid;
  888. {
  889.         int             i;
  890.  
  891.         for (i = 0; i < num_notifys; i++) 
  892.                 if (notifylist[i].for_who == for_who &&
  893.                         notifylist[i].on_tid == on_tid) {
  894.                         break;
  895.                 }
  896.  
  897.         if (i >= num_notifys) {
  898. #ifdef DEBUG_RM
  899.                 fprintf(stderr, "del_notification: Unable to find notify struct\n");
  900. #endif
  901.                 return -1;
  902.         }
  903.  
  904.         notifylist[i] = notifylist[num_notifys - 1];
  905. #ifdef DEBUG_RM
  906.     printf ("Deleteing notify\n");
  907. #endif
  908.         num_notifys--;
  909.         return 0;
  910. }
  911.  
  912. int
  913. new_notification(kind, for_who, msg_tag, on_tid, ctx)
  914. int kind, for_who, msg_tag, on_tid, ctx;
  915. {
  916. #ifdef DEBUG_RM
  917.     printf ("For_whom t%x, On_tid t%x\n", for_who, on_tid);
  918. #endif
  919.         if (notify_list_size == 0) {
  920.                 notify_list_size = 10;
  921.                 notifylist = (struct notification *) malloc(notify_list_size *
  922.  
  923.                  sizeof(struct notification));
  924.         }
  925.         if (num_notifys + 1 >= notify_list_size) {
  926.                 notify_list_size *= 2;
  927.                 notifylist = (struct notification *) realloc(notifylist,
  928.                          notify_list_size *
  929.                   sizeof(struct notification));
  930.         }
  931.  
  932.         notifylist[num_notifys].kind = kind;
  933.         notifylist[num_notifys].for_who = for_who;
  934.         notifylist[num_notifys].msg_tag = msg_tag;
  935.         notifylist[num_notifys].on_tid = on_tid;
  936.     notifylist[num_notifys].m_ctx = ctx;
  937.  
  938.         num_notifys++;
  939. #ifdef DEBUG_RM
  940.     printf ("Setting up notify with kind %d\n", kind);
  941. #endif
  942.         return 0;
  943. }
  944.  
  945. int
  946. print_host_contents()
  947. {
  948.     host_type *host;
  949.     int    i = 0;
  950.  
  951.     for ( host= HOST_HEAD.next; host; host = host->next)
  952.     {
  953.         printf("\n\n");
  954.         printf("Entry %d\n", i);
  955.         printf("Load %d\n",host->load);
  956.         printf("Host Tid t%x\n",host->entry.hi_tid);
  957.         printf("Host name %s\n",host->entry.hi_name);
  958.         printf("Host arch %s\n",host->entry.hi_arch);
  959.         printf("Host speed %d\n",host->entry.hi_speed);
  960.         printf("Host signature %x\n",host->entry.hi_dsig);
  961.         printf("\n\n");
  962.         i++;
  963.     }
  964.     return 1;
  965. }
  966.  
  967.